package com.cool.modules.finance.controller.admin;

import cn.hutool.json.JSONObject;
import com.cool.core.annotation.CoolRestController;
import com.cool.core.base.BaseController;
import com.cool.core.request.R;
import com.cool.core.util.CoolSecurityUtil;
import com.cool.modules.base.entity.sys.table.BaseSysUserEntityTableDef;
import com.cool.modules.finance.constant.AccountType;
import com.cool.modules.finance.dto.FinanceTransferAccountVo;
import com.cool.modules.finance.entity.account.FinanceAccountEntity;
import com.cool.modules.finance.entity.account.FinanceTrialBalanceEntity;
import com.cool.modules.finance.entity.account.table.FinanceAccountEntityTableDef;
import com.cool.modules.finance.entity.coin.table.FinanceCoinEntityTableDef;
import com.cool.modules.finance.service.account.FinanceAccountService;
import com.cool.modules.finance.service.account.FinanceTransferAccountService;
import com.cool.modules.finance.service.account.FinanceTrialBalanceService;
import com.cool.modules.finance.service.family.FinanceUserFamilyService;
import com.mybatisflex.core.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

@Tag(name = "账户管理", description = "账户管理")
@CoolRestController(api = { "add", "delete", "update", "list","page" })
@RequiredArgsConstructor
public class AdminFinanceAccountController extends BaseController<FinanceAccountService, FinanceAccountEntity> {

    /**
     * 转账记录
     */
    final FinanceTransferAccountService transferAccountService;

    final FinanceTrialBalanceService trialBalanceService;

    final FinanceUserFamilyService userFamilyService;

    @Override
    protected void init(HttpServletRequest request, JSONObject requestParams) {
        FinanceAccountEntity bean = requestParams.toBean(FinanceAccountEntity.class);
        FinanceCoinEntityTableDef coin = FinanceCoinEntityTableDef.FINANCE_COIN_ENTITY.as("coin");
        FinanceAccountEntityTableDef account = FinanceAccountEntityTableDef.FINANCE_ACCOUNT_ENTITY;
        setPageOption(createOp().
                keyWordLikeFields(
                        account.ACCOUNT_NAME,
                        account.ACCOUNT_CODE).
                queryWrapper(new QueryWrapper().select(account.ALL_COLUMNS, coin.COIN_NAME.as(FinanceAccountEntity::getCoinName), coin.SYMBOL.as(FinanceAccountEntity::getCoinSymbol)).
                        leftJoin(coin).on(coin.ID.eq(account.COIN_ID)).
                        eq(FinanceAccountEntity::getIsCancel,bean.getIsCancel(),bean.getIsCancel()!=null).
                        eq(FinanceAccountEntity::getAccountType,bean.getAccountType(),bean.getAccountType()!=null).
                        eq(FinanceAccountEntity::getCoinId,bean.getCoinId(),bean.getCoinId()!=null).
                        eq(FinanceAccountEntity::getOwnedAccount, CoolSecurityUtil.getCurrentUserId()).
                        orderBy(FinanceAccountEntity::getIsCancel,true)).
                transform(obj -> {
                    FinanceAccountEntity entity = (FinanceAccountEntity) obj;
                    if (null!=entity.getRedeemAccount()){
                        entity.setRedeemAccountName(service.getById(entity.getRedeemAccount()).getAccountName());
                    }
                    List<FinanceTrialBalanceEntity> list = trialBalanceService.list(new QueryWrapper().eq(FinanceTrialBalanceEntity::getAccountId, entity.getId()).orderBy(FinanceTrialBalanceEntity::getTrialDate, false));
                    Optional<FinanceTrialBalanceEntity> first = list.stream().filter(FinanceTrialBalanceEntity::getIsFinal).findFirst();
                    if (first.isPresent()){
                        FinanceTrialBalanceEntity trialBalance = first.get();
                        entity.setRate(trialBalance.getRate());
                        entity.setMedianRate(trialBalance.getMedianRate());
                    }else {
                        list.stream().findFirst().ifPresent(trialBalance -> {
                            entity.setRate(trialBalance.getRate());
                            entity.setMedianRate(trialBalance.getMedianRate());
                        });
                    }
                })
        );
        //非取消的当前账户按照热度排序
        setListOption(createOp().queryWrapper(new QueryWrapper().select(account.ALL_COLUMNS,
                coin.ID.as(FinanceAccountEntity::getCoinId),
                coin.COIN_NAME.as(FinanceAccountEntity::getCoinName),
                coin.SYMBOL.as(FinanceAccountEntity::getCoinSymbol)).
                from(account).
                leftJoin(coin).on(coin.ID.eq(account.COIN_ID)).
                where(account.IS_CANCEL.eq(false)).
                        and(account.OWNED_ACCOUNT.eq(CoolSecurityUtil.getCurrentUserId())).
                        and(account.ACCOUNT_TYPE.eq(bean.getAccountType()).when(bean.getAccountType()!=null)).
                        and(coin.ID.eq(bean.getCoinId()).when(bean.getCoinId()!=null)).
                        orderBy(account.HOT_ORDER,false)));
    }

    @Override
    protected FinanceAccountEntity buildSubData(QueryWrapper queryWrapper) {
        List<FinanceAccountEntity> list = service.list(queryWrapper);
        FinanceAccountEntity entity = new FinanceAccountEntity();
        entity.setAccountBalance(list.stream().map(FinanceAccountEntity::getAccountBalance).reduce(BigDecimal.ZERO,BigDecimal::add));
        entity.setAccountMoney(list.stream().map(FinanceAccountEntity::getAccountMoney).reduce(BigDecimal.ZERO,BigDecimal::add));
        return entity;
    }

    @Operation(summary = "查询历史转账记录", description = "查询历史转账记录")
    @PostMapping("/historyTransfer")
    public R transferList(@RequestAttribute() JSONObject requestParams) {
        return R.ok(transferAccountService.getTransferAccountList(requestParams));
    }

    @Operation(summary = "转账的树形列表", description = "转账的树形列表")
    @PostMapping("/treeAccount")
    public R treeAccountList(@RequestAttribute() JSONObject requestParams){
        return R.ok(service.treeAccount(requestParams));
    }

    /**
     * 转账
     * @param requestParams
     * @return
     */
    @Operation(summary = "去转账", description = "去转账")
    @PostMapping("/accountTransfer")
    public R accountTransfer(@RequestAttribute() JSONObject requestParams){
        FinanceTransferAccountVo transferAccountVo = requestParams.toBean(FinanceTransferAccountVo.class);
        return R.ok(service.transfer(transferAccountVo));
    }


    @Operation(summary = "撤销转账记录", description = "撤销转账记录")
    @PostMapping("/delTransfer")
    public R delTransfer(@RequestAttribute() JSONObject requestParams){
        return R.ok(service.delTransfer(requestParams));
    }


    @Operation(summary = "赎回理财账户", description = "赎回理财账户")
    @PostMapping("/redeem")
    public R redeemAccount(@RequestAttribute() JSONObject requestParams){
        return R.ok(service.redeemAccount(requestParams));
    }

    @Operation(summary = "支付列表", description = "支付列表")
    @PostMapping("/payList")
    protected R payList(@RequestAttribute() JSONObject requestParams) {
        FinanceAccountEntityTableDef account = FinanceAccountEntityTableDef.FINANCE_ACCOUNT_ENTITY;
        FinanceCoinEntityTableDef coin = FinanceCoinEntityTableDef.FINANCE_COIN_ENTITY;
        QueryWrapper query = new QueryWrapper();
        query.select(account.ALL_COLUMNS,coin.ID.as(FinanceAccountEntity::getCoinId), coin.COIN_NAME.as(FinanceAccountEntity::getCoinName), coin.SYMBOL.as(FinanceAccountEntity::getCoinSymbol)).
                from(account).leftJoin(coin).on(coin.ID.eq(account.COIN_ID)).
                where(account.IS_CANCEL.eq(false)).
                and(account.OWNED_ACCOUNT.eq(CoolSecurityUtil.getCurrentUserId())).
                and(account.ACCOUNT_TYPE.ne(AccountType.FINANCE.getType())).
                orderBy(account.HOT_ORDER,false);
        return R.ok(service.list(query));
    }

    @Operation(summary = "家庭单位下支付列表", description = "家庭单位下支付列表")
    @PostMapping("/allPayList")
    protected R allPayList(@RequestAttribute() JSONObject requestParams) {
        FinanceAccountEntityTableDef account = FinanceAccountEntityTableDef.FINANCE_ACCOUNT_ENTITY;
        FinanceCoinEntityTableDef coin = FinanceCoinEntityTableDef.FINANCE_COIN_ENTITY;
        BaseSysUserEntityTableDef sysUser = BaseSysUserEntityTableDef.BASE_SYS_USER_ENTITY;

        QueryWrapper query = new QueryWrapper();
        query.select(account.ALL_COLUMNS, sysUser.NAME.as(FinanceAccountEntity::getOwnedAccountName),
                coin.ID.as(FinanceAccountEntity::getCoinId), coin.COIN_NAME.as(FinanceAccountEntity::getCoinName),coin.SYMBOL.as(FinanceAccountEntity::getCoinSymbol)).
                from(account).leftJoin(sysUser).on(sysUser.ID.eq(account.OWNED_ACCOUNT)).
                leftJoin(coin).on(coin.ID.eq(account.COIN_ID)).
                where(account.IS_CANCEL.eq(false)).
                and(account.OWNED_ACCOUNT.in(userFamilyService.getFamilyUserIdsByUserId(CoolSecurityUtil.getCurrentUserId()))).
                and(account.ACCOUNT_TYPE.ne(AccountType.FINANCE.getType())).
                orderBy(FinanceAccountEntity::getHotOrder,false);
        return R.ok(service.list(query));
    }


}
